from PIL import Image
import os
import math
import requests,threading,time

PATH="E:/User/Desktop/MAP/"#地图下载路径，自行修改

header={
    # "Host": "services.arcgisonline.com",
    # "Sec-Fetch-Dest": "document",
    # "Sec-Fetch-User": "?1",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53"
}
def lngToPx(lng,z): 
    lenth=2**z
    x=int((0.5+lng/180*0.5)*lenth)
    return x
def latToPx(lat,z):
    lenth=2**z
    siny=math.sin(lat*math.pi/180)
    y=math.log((1+siny)/(1-siny))
    y=int((lenth*0.5)*(1-y/(2*math.pi)))
    return y

def delete_file():
    FORMAT = ['.jfif','.jpg']
    file_names = [name for name in os.listdir(PATH) for item in FORMAT if os.path.splitext(name)[1] == item]
    for name in os.listdir(PATH):
        if os.path.splitext(name)[1] in FORMAT:
            # print('delete:',name)
            os.remove(PATH+name)
        # print()
def image_compose():
    
    IMAGES_PATH = PATH  # 图片集地址
    IMAGES_FORMAT = ['.jfif']  # 图片格式
    IMAGE_SIZE = 256  # 每张小图片的大小
    IMAGE_ROW = 6  # 图片间隔，也就是合并成一张图后，一共有几行
    IMAGE_COLUMN = 6  # 图片间隔，也就是合并成一张图后，一共有几列
    IMAGE_SAVE_PATH = PATH+'gisoracle.jpg'  # 图片转换后的地址
    # 获取图片集地址下的所有图片名称
    image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if
               os.path.splitext(name)[1] == item]

    # 简单的对于参数的设定和实际图片集的大小进行数量判断
    if len(image_names) != IMAGE_ROW * IMAGE_COLUMN:
        raise ValueError("合成图片的参数和要求的数量不能匹配！")
    to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE))  # 创建一个新图
    # 循环遍历，把每张图片按顺序粘贴到对应位置上
    for y in range(1, IMAGE_ROW + 1):
        for x in range(1, IMAGE_COLUMN + 1):
            from_image = Image.open(IMAGES_PATH + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize(
                (IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
            to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))
    return to_image.save(IMAGE_SAVE_PATH)  # 保存新图

result = {}
def retry_get(url,times=5):
    for i in range(0,times):
        try:
            req = requests.get(url)
            return req
        except Exception:
            url=str(url).replace("/arcgis/","/ARCGIS/")
            continue
def down_load_pic(url,name):
    req = retry_get(url)
    with open( PATH+name,'wb') as fw:
        fw.write(req.content)


def map_search(longitude,latitude,size):
    z=size
    x=lngToPx(float(longitude),z)
    y=latToPx(float(latitude),z)
    print(x,y,z)
    URL=[]
    NAME=[]
    for i in range(0,6):
        for j in range(0,6):
            url2='http://maponline3.bdimg.com/starpic/?qt=satepc&u=x={};y={};z={};v=009;type=sate'.format(str(x+j-3),str(y+i-3),str(z))
            url='https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{}/{}/{}'.format(str(z),str(y+i-3),str(x+j-3))
            URL.append(url)
            NAME.append(str(i)+'-'+str(j)+'.jfif')
    return (URL,NAME)

# im=Image.open(map_search())
# im.show()
#多线程下载
def down_load_map(longitude,latitude,size):
    # delete_file()
    start_time = time.time()
    URL,NAME=map_search(longitude,latitude,size)
    for url ,name in zip(URL,NAME):
        # print(name,url)
        t = threading.Thread(target=down_load_pic,args=(url,name,))
        t.start()
    while threading.activeCount() !=1:
        end_time = time.time()
        if end_time-start_time>10:
            break
    print(end_time - start_time)
    image_compose()
    return PATH+'gisoracle.jpg'

def mercatorTolonlat(x,y):
    lonlat=[0,0]
    n1=2003880800.34
    n2=1992550800.34
    x = x/n1*180
    y = y/n2*180
    y= 180/math.pi*(2*math.atan(math.exp(y*math.pi/180))-math.pi/2)
    lonlat[0] = x
    lonlat[1] = y
    return lonlat

def find_location(city):
    url='https://api.map.baidu.com/geocoding/v3/?address={}&output=json&ak=gQsCAgCrWsuN99ggSIjGn5nO'.format(city)
    headers={
        "Host": "api.map.baidu.com",
        "Referer": "https://maplocation.sjfkai.com/"
    }
    content=requests.get(url,headers=headers,timeout=5).json()
    lon=content["result"]["location"]["lng"]
    lat=content["result"]["location"]["lat"]
    return (float(lon),float(lat))

city="长沙"
lon,lat=find_location(city)#获取城市经纬度
size=12#地图倍数
print(city,"lon:",lon,"lat:",lat)
down_load_map(lon,lat,size)